#include "stdafx.h"
#include "QMainFrame.h"
#include "Game.h"
#include "QCompile.h"

bool QCompile::useUtils[MAXUTILS];
wxString QCompile::utilParams[MAXUTILS];
int QCompile::utilParamIndex;
int QCompile::compileStage = -1;

BEGIN_EVENT_TABLE(QCompile, wxDialog)
	EVT_CHOICE(QID_COMPILE_CURRENT_UTIL, QCompile::OnChoiceUtil)
	EVT_BUTTON(wxID_OK, QCompile::OnOK)
END_EVENT_TABLE()

QCompile::QCompile(wxWindow *parent)
	: wxDialog(parent, wxID_ANY, _("Compile Map"), wxDefaultPosition)
{
	// Initialize the controls.
	currentUtil = NULL;
	currentUtilParams = NULL;
	for(int i = 0; i < MAXUTILS; i++)
		useUtilBox[i] = NULL;

	// Create the layout of the dialog.
	CreateLayout();

	// Get the game.
	Game *game = GetMainFrame()->GetDeskTopDocument()->GetGame();
	int numutils = game->GetNumUtils();

	// Load the compile params
	game->InitCompileParams(useUtils, utilParams, utilParamIndex);

	// Set the current state.
	for(int i = 0; i < numutils; i++)
	{
		currentUtil->Append(game->GetUtilName(i));
		useUtilBox[i]->SetValue(useUtils[i]);
	}

	currentUtil->SetSelection(utilParamIndex);
	currentUtilParams->SetValue(utilParams[utilParamIndex]);

}

QCompile::~QCompile()
{
}

void QCompile::CreateLayout()
{
	// Get the game.
	Game *game = GetMainFrame()->GetDeskTopDocument()->GetGame();
	int numutils = game->GetNumUtils();
	ASSERT(numutils <= MAXUTILS);

	// Create the dialog layout.
	wxBoxSizer *dialogSizer = new wxBoxSizer(wxVERTICAL);

	wxBoxSizer *checkSizer = new wxBoxSizer(wxVERTICAL);
	dialogSizer->Add(checkSizer, 0, wxALL, 5);

	wxStaticText *label = new wxStaticText(this, wxID_ANY, _("Run Utilities:"));
	checkSizer->Add(label, 0, wxALL, 5);

	// Create a checkbox for each utility
	for(int i = 0; i < numutils; i++)
	{
		useUtilBox[i] = new wxCheckBox(this, QID_COMPILE_USE_UTIL_START + i,
				game->GetUtilName(i));
		checkSizer->Add(useUtilBox[i]);
	}

	// Create a section to set the arguments of each utility.
	wxStaticBoxSizer *argBoxSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Parameters"));
	dialogSizer->Add(argBoxSizer, 0, wxEXPAND|wxALL, 5);

	// Add a choice to select the utility.
	currentUtil = new wxChoice(this, QID_COMPILE_CURRENT_UTIL);
	argBoxSizer->Add(currentUtil);

	// Add a text control with the parameters.
	currentUtilParams = new wxTextCtrl(this, QID_COMPILE_UTIL_PARAMS, wxT(""),
			wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
	argBoxSizer->Add(currentUtilParams, 0, wxEXPAND);

	// Add the dialog buttons.
	wxSizer *buttonSizer = CreateButtonSizer(wxOK|wxCANCEL);
	dialogSizer->Add(buttonSizer, 0, wxALIGN_RIGHT|wxALL, 5);

	// Set the sizer.
	SetSizer(dialogSizer);
	dialogSizer->Fit(this);
}

void QCompile::OnChoiceUtil(wxCommandEvent &event)
{
	int &oldSelection = utilParamIndex;
	int newSelection = event.GetSelection();

	// Store the the old util params.
	utilParams[oldSelection] = currentUtilParams->GetValue();

	// Display the new util params.
	currentUtilParams->SetValue(utilParams[newSelection]);

	// Update the old selection.
	oldSelection = newSelection;
}

void QCompile::OnOK(wxCommandEvent &event)
{
	// Get the game.
	Game *game = GetMainFrame()->GetDeskTopDocument()->GetGame();
	int numutils = game->GetNumUtils();

	// Store the current choice.
	utilParamIndex = currentUtil->GetSelection();
	utilParams[utilParamIndex] = currentUtilParams->GetValue();

	// Store the value of the check boxes.
	for(int i = 0; i < numutils; i++)
	{
		useUtils[i] = useUtilBox[i]->GetValue();
	}

	// Save the state.
	game->SaveCompileParams(useUtils, utilParams, utilParamIndex);

	// Init the compile stage.
	compileStage = 0;

	// Continue propagating.
	event.Skip();
}

void QCompile::ExecuteCompiles()
{
	QProcessWindow *proc = GetMainFrame()->GetProcessWindow();
	QooleDoc *doc = GetMainFrame()->GetDeskTopDocument();
	Game *game = doc->GetGame();
	wxString docName = doc->GetDocName();
	int numUtils = game->GetNumUtils();
	ASSERT(compileStage >= 0 && compileStage <= numUtils);

	// Find the next compile stage.
	for(int i = 0; i < numUtils; i++)
	{
		if(compileStage == i && !useUtils[i])
			compileStage++;
	}

	// TODO: Check to resume render library

	// Check if compiles finished.
	if(compileStage == numUtils)
	{
		compileStage = -1;
		return;
	}

	// Check for the first compile stage.
	if(compileStage == 0)
	{
		// Clear the window.
		proc->ClearWindow();

		// Export the map first.
		wxString mapPath = game->GetMapExportPath(docName, PrintText);
		if(mapPath.empty())
		{
			compileStage = -1;
			return;
		}

		PrintText(wxString::Format(_("Saving file: %s\n\n"), mapPath.c_str()));
		if(!doc->ExportDocument(mapPath))
		{
			compileStage = -1;
			PrintText(_("Failed to save file."));
		}
	}

	// Get the util command line.
	wxString commandLine, initDir;
	if(!game->GetUtilCmdLine(compileStage, docName,
			&commandLine, &initDir,	PrintText))
	{
		compileStage = -1;
		return;
	}

	// Run the util.
	ASSERT(!proc->IsProcessRunning());

	compileStage++;
	proc->ExecProcess(commandLine, initDir, &ExecuteCompiles);
}

void QCompile::StopCompiles()
{
}

void QCompile::PrintText(const wxChar *text)
{
	ASSERT(text != NULL);

	QProcessWindow *proc = GetMainFrame()->GetProcessWindow();
	ASSERT(proc != NULL);

	proc->OutputText(text);
}

void QCompile::PrintText(const wxString &text)
{
	PrintText(text.c_str());
}


